package com.lime49.lockcrypt.idletimer;

import com.sun.jna.ptr.IntByReference;

/**
 *
 */
public class LinuxIdleTimer implements IIdleTimer {

/**
 * Linux system info.
 * 
 * Based on
 * https://jdic.dev.java.net/source/browse/jdic/src/incubator/systeminfo
 * /src/unix/native/jni/systeminfo.c?rev=1.1.1.1&view=markup source code.
 * 
 * @author chatellier
 * @version $Revision$
 * 
 * Last update : $Date$
 * By : $Author$
 */
    /**
     * Constructor.
     * 
     * Package visibility
     */
    public LinuxIdleTimer() {
    }

    @Override
    public int getIdleTimeMillis() {
        int idleTime = 0;

        try {
            idleTime = (int)getXssIdleTime();
        } catch (Exception e) {
            idleTime = 0;
        }
        return idleTime;
    }

    /**
     * Get idle time via Xss.
     * 
     * @return idle time
     */
    protected long getXssIdleTime() throws Exception {

        long idleTime = 0;

        // get X11 display
        X11.Display display = X11.INSTANCE.XOpenDisplay(null);
        if (display == null) {
            throw new Exception("Can't open X11 display");
        } else {
            // Display is opened

            // check if screensaver extension is enabled
            IntByReference eventBase = new IntByReference();
            IntByReference errorBase = new IntByReference();

            if (!Xss.INSTANCE.XScreenSaverQueryExtension(display, eventBase, errorBase)) {
                    throw new Exception("Can't find xscreensaver extension, idle time can't be detected");
            } else {
                // screensaver is enabled

                Xss.XScreenSaverInfo screenSaverInfo = Xss.INSTANCE.XScreenSaverAllocInfo();

                if (screenSaverInfo == null) {
                    throw new Exception("Could not alloc screen saver info");
                } else {
                    // get root window
                    X11.Window rootWindow = X11.INSTANCE
                            .XDefaultRootWindow(display);

                    if (rootWindow == null) {
                        throw new Exception("Could not query root window");
                    } else {

                        // FIX : without this, cause random NPE
                        screenSaverInfo.window = rootWindow;

                        Xss.INSTANCE.XScreenSaverQueryInfo(display, rootWindow,
                                screenSaverInfo);
                        if (screenSaverInfo.idle == null) {
                            throw new Exception("screenSaverInfo.idle is null");
                        } else {
                            idleTime = screenSaverInfo.idle.longValue();
                        }
                    }
                }

                // free resources
                // TODO should be freed
                //X11.INSTANCE.XFree(screenSaverInfo);
            }

            // free resources
            X11.INSTANCE.XCloseDisplay(display);
        }

        return idleTime;
    }
}
